import socket
import time
import struct

# 设备信息
ip_address = '192.168.10.11'
port = 5020


# 要读取的寄存器地址,Modbus TCP 请求帧：是否存在撕裂
transaction_id = 0x1234
unit_id = 0x01

# 是否存在撕裂
register_address_if = 0x003  # 适当设置要读取的寄存器地址
function_code_if = 0x01

# 建立撕裂数请求帧
register_address_num = 0x014
function_code_num = 0x04

# 建立撕裂最大长度请求帧
register_address_Length = 0x015
function_code_Length = 0x04


##########################################################################################
# 是否存在撕裂发送帧
def ExistTear(register_address):
    return bytearray([
        transaction_id >> 8, transaction_id & 0xFF,
        0x00, 0x00,  # Protocol Identifier
        0x00, 0x06,  # Length
        unit_id,
        function_code_if,
        register_address >> 8, register_address & 0xFF,
        0x00, 0x01  # Read one register
    ])


##########################################################################################
# 撕裂数目信息发送帧
def TearNum(register_address):
    return bytearray([
        transaction_id >> 8, transaction_id & 0xFF,
        0x00, 0x00,  # Protocol Identifier
        0x00, 0x06,  # Length
        unit_id,
        function_code_num,
        register_address >> 8, register_address & 0xFF,
        0x00, 0x01  # Read one register
    ])


##########################################################################################
# 最大撕裂长度信息发送帧
def TearLength(register_address):
    return bytearray([
        transaction_id >> 8, transaction_id & 0xFF,
        0x00, 0x00,  # Protocol Identifier
        0x00, 0x06,  # Length
        unit_id,
        function_code_Length,
        register_address >> 8, register_address & 0xFF,
        0x00, 0x02  # Read one register
    ])


# 创建 Socket 连接
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ip_address, port))

try:
    while True:

        ##########################################################################################
        # 是否出现撕裂请求
        request_frame_if = ExistTear(register_address_if)

        # 发送请求帧
        client_socket.send(request_frame_if)

        # 接收响应帧
        response_frame_if = client_socket.recv(1024)

        # 解析响应帧
        if len(response_frame_if) >= 9 and response_frame_if[7] == function_code_if:
            # data = response_frame[9] << 8 | response_frame[10]
            i1 = int.from_bytes(response_frame_if[9:], byteorder='big', signed=True)
            # print("皮带撕裂情况:", i1)

            if i1 == 0:

                print("未发现皮带撕裂。")
            elif i1 == 1:

                print("皮带出现撕裂！")

        else:
            print("Read Error")

        ##########################################################################################
        # 撕裂数目信息请求

        request_frame_num = TearNum(register_address_num)

        # 发送请求帧
        client_socket.send(request_frame_num)

        # 接收响应帧
        response_frame_num = client_socket.recv(1024)

        # 解析响应帧
        if len(response_frame_num) >= 9 and response_frame_num[7] == function_code_num:
            # data = response_frame[9] << 8 | response_frame[10]
            i2 = int.from_bytes(response_frame_num[9:], byteorder='big', signed=True)
            # print("皮带撕裂数:", i2)
            if i2 != 0:
                print("皮带撕裂数:", i2)
        else:
            print("Modbus Read Error")

        ##########################################################################################
        # 撕裂最大长度请求

        request_frame_Length = TearLength(register_address_Length)

        # 发送请求帧
        client_socket.send(request_frame_Length)

        # 接收响应帧
        response_frame_Length = client_socket.recv(1024)

        # 解析响应帧
        if len(response_frame_Length) >= 9 and response_frame_Length[7] == function_code_Length:
            # data = response_frame_Length[9] << 8 | response_frame_Length[10]
            i3 = struct.unpack('!f', response_frame_Length[9:])[0]
            # print("皮带最大撕裂长度:", i3)
            if i3 != 0:
                print("皮带最大撕裂长度:", i3)
        else:
            print("Modbus Read Error")
        time.sleep(0.5)


except KeyboardInterrupt:

    pass


# 关闭连接
client_socket.close()
